<script setup lang="tsx">
// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 模块导入 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

import { nextTick, onMounted, ref, shallowRef } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import type { AMap } from 'amap-js-api';
import type { TreeOption } from 'naive-ui';
import { useDict } from '@/hooks/business/dict';
import { fetchGetCjTaskList, fetchGetOrgUnitTree, getLocation } from '@/service/api';
import { StringUtil, TreeUtil } from '@/utils/z';

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 组件名称 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

defineOptions({
  name: 'SamplingMapView'
});

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 常量、类型 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 组合式函数 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

const { dictOptions } = useDict();

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 父子传参 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 框架模型 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 业务模型 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// 本页面存在树下拉列表，需要在模型初始化时进行控制重新渲染
const treeSelectShow = ref<boolean>(false);

const myOrgTree = shallowRef<Api.SystemManage.OrgUnitTree[]>([]);

const orgTreeOptions = shallowRef<TreeOption[]>([]);

const pYear = ref<string>('');

const orgId = ref('');

const samplingType = ref('');

const taskStatus = ref('');

const lat = ref('');

const lng = ref('');

const positionCode = ref<string>('');

let AMap: any = null;

let mapInstance: any = null;

let markers: any = [];

/** 页面统计 */
const recordNum = ref<number>(0);

const tasks = ref<Api.Sampling.Record[]>([]);

const task = ref<Api.Sampling.Record | null>(null);

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 框架方法 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 业务方法 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

// 初始化组织树下拉列表
async function initOrgTreeOptions() {
  const { error, data } = await fetchGetOrgUnitTree();
  if (!error && data) {
    myOrgTree.value = data;
    orgTreeOptions.value = data.map(toTreeOptionNode);
  }
}

function toTreeOptionNode(item: Api.SystemManage.OrgUnitTree): TreeOption {
  const option: TreeOption = {
    key: item.id,
    label: item.name
  };
  if (item.children && item.children.length > 0) {
    option.children = item.children.map(toTreeOptionNode);
  }
  return option;
}

// 渲染地图
async function renderMap() {
  AMap = await AMapLoader.load({
    key: '389c549d9852dada7b92493a0d967a55',
    version: '2.0',
    plugins: []
  });

  mapInstance = new AMap.Map('container', {
    zoom: 11,
    center: [lng.value || 116.397428, lat.value || 39.90923]
  });
}

// 添加标记点
function addMarkers(points: any) {
  if (!mapInstance) {
    return;
  }

  // 先清除旧标记（可选）
  clearMarkers();

  // 遍历坐标点创建标记
  points.forEach((point: any) => {
    const marker = new AMap.Marker({
      position: new AMap.LngLat(point.lng, point.lat),
      title: point.title || '标记点'
    });
    marker.on('click', () => {
      // 弹窗显示详细信息
      window.$message?.info(`📍 经度：${point.lng}\n纬度：${point.lat}`);
      const arr = tasks.value.filter(x => x.taskId === point.title);
      task.value = arr.length > 0 ? arr[0] : null;
    });
    markers.push(marker);
    mapInstance.add(marker); // 将标记添加到地图
  });

  // 自动调整地图视野以包含所有标记
  mapInstance.setFitView();
}

function clearMarkers() {
  if (mapInstance && markers.length > 0) {
    mapInstance.remove(markers);
    markers = [];
  }
}

function reset() {
  pYear.value = '';
  orgId.value = '';
  treeSelectShow.value = false;
  nextTick(() => {
    treeSelectShow.value = true;
  });
  samplingType.value = '';
  taskStatus.value = '';
  positionCode.value = '';
  clearMarkers();
  recordNum.value = 0;
  tasks.value = [];
  task.value = null;
}

/**
 * 获取位置信息
 *
 * 调用 getLocation 函数获取位置信息，并在获取成功后设置地图中心点，并添加标记点
 */
async function getLocationInfo() {
  const { error, data } = await getLocation();
  if (!error && data) {
    const { longitude, latitude } = data;
    // const point = new AMap.LngLat(longitude, latitude);
    // mapInstance.setCenter(point);
    const addressInfo: any = [];
    lat.value = latitude;
    lng.value = longitude;
    addressInfo.push({ lng: Number(longitude), lat: Number(latitude) });
    // addMarkers(addressInfo);
    renderMap();
    mapInstance.setFitView();
  }
}

async function search() {
  if (
    StringUtil.isEmpty(pYear.value) &&
    StringUtil.isEmpty(orgId.value) &&
    StringUtil.isEmpty(samplingType.value) &&
    StringUtil.isEmpty(taskStatus.value) &&
    StringUtil.isEmpty(positionCode.value)
  ) {
    window.$message?.error('请设置查询条件！');
    return;
  }
  const params: Api.Sampling.CjTask.ListParams = {
    year: pYear.value,
    orgId: orgId.value,
    samplingType: samplingType.value,
    taskStatus: taskStatus.value,
    code: positionCode.value
  };
  const { error, data } = await fetchGetCjTaskList(params);
  if (!error && data) {
    tasks.value = data;
    const points: any = [];
    data.forEach(item => {
      points.push({ lng: Number(item.gcj02Longitude), lat: Number(item.gcj02Latitude), title: item.taskId });
    });
    recordNum.value = points.length;
    window.$message?.error(`本次共查询到 ${recordNum.value} 个点位`);
    addMarkers(points);
    task.value = null;
  }
}

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 框架生命周期 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++

onMounted(async () => {
  treeSelectShow.value = false;
  await initOrgTreeOptions();
  treeSelectShow.value = true;

  renderMap().then(() => {
    // const points = [
    //   { lng: 116.397428, lat: 39.90923, title: '天安门' },
    //   { lng: 116.403322, lat: 39.920255, title: '故宫' },
    //   { lng: 116.340456, lat: 39.940015, title: '颐和园' }
    // ];
    addMarkers(points);
  });
  await getLocationInfo();
});

// +++++++++++++++++++++++++++++++++++++++++++++++
// ---------- 业务生命周期 ----------
// +++++++++++++++++++++++++++++++++++++++++++++++
</script>

<template>
  <NGrid x-gap="8" cols="6" item-responsive responsive="screen">
    <NGridItem span="1">
      <div class="flex">
        <NTag size="large" :bordered="false" style="background-color: transparent">采样年份</NTag>
        <div class="mb-8px ml-5px flex-1">
          <NInput v-model:value="pYear" type="text" placeholder="请输入采样年份" clearable />
        </div>
      </div>
      <div class="flex">
        <NTag size="large" :bordered="false" style="background-color: transparent">承担单位</NTag>
        <div class="mb-8px ml-5px flex-1">
          <template v-if="treeSelectShow">
            <NTreeSelect :options="orgTreeOptions" :default-value="orgId" clearable @update:value="val => (orgId = val)" />
          </template>
        </div>
      </div>
      <div class="flex">
        <NTag size="large" :bordered="false" style="background-color: transparent">点位编码</NTag>
        <div class="mb-8px ml-5px flex-1">
          <NInput v-model:value="positionCode" type="text" clearable />
        </div>
      </div>
      <div class="flex">
        <NTag size="large" :bordered="false" style="background-color: transparent">任务类别</NTag>
        <div class="mb-8px ml-5px flex-1">
          <NSelect v-model:value="samplingType" :options="dictOptions('cj_sampling_type')" clearable />
        </div>
      </div>
      <div class="flex">
        <NTag size="large" :bordered="false" style="background-color: transparent">任务状态</NTag>
        <div class="mb-8px ml-5px flex-1">
          <NSelect v-model:value="taskStatus" :options="dictOptions('cj_task_status')" clearable />
        </div>
      </div>
      <NGrid x-gap="8" cols="2" item-responsive responsive="screen">
        <NGridItem span="1">
          <NButton type="warning" class="mb-12px w-100%" @click="reset">重置</NButton>
        </NGridItem>
        <NGridItem span="1">
          <NButton type="primary" class="mb-12px w-100%" @click="search">查询</NButton>
        </NGridItem>
      </NGrid>
      <div class="text-[#595959]" style="text-align: left">
        <table border="0" cellpadding="0" cellspacing="0" class="w-100%" style="text-align: left">
          <tbody>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px" style="width: 100px">📍点位数量</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ recordNum }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px" colspan="2">📍点击点位信息：</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">省</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">
                {{ StringUtil.isNotEmpty(task?.province) ? TreeUtil.findNodeInOrgTree(myOrgTree, task!.province)!.name : '' }}
              </td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">市</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">
                {{ StringUtil.isNotEmpty(task?.city) ? TreeUtil.findNodeInOrgTree(myOrgTree, task!.city)!.name : '' }}
              </td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">县</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">
                {{ StringUtil.isNotEmpty(task?.county) ? TreeUtil.findNodeInOrgTree(myOrgTree, task!.county)!.name : '' }}
              </td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">乡镇</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.town || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">村</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.village || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">组</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.team || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px" colspan="2">是否自动定位：{{ task?.autoLngLat ? '是' : '否' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">经度</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.wgs84Longitude || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">维度</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.wgs84Latitude || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">海拔</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.wgs84Altitude || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">屏显经度</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.screenLongitude || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">屏显维度</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.screenLatitude || '' }}</td>
            </tr>
            <tr>
              <td class="bg-[#f5f5f5] pb-2px pl-5px pr-5px pt-2px">屏显海拔</td>
              <td class="pb-2px pl-5px pr-5px pt-2px">{{ task?.screenAltitude || '' }}</td>
            </tr>
          </tbody>
        </table>
        <span class="mt-8px inline-block text-12px text-[#999]">说明：采用 CGCS2000 坐标系。</span>
      </div>
    </NGridItem>
    <NGridItem span="5">
      <div style="width: 100%; height: 100%; position: relative; padding: 1px; border: 1px solid #e5e7eb; border-radius: 4px">
        <div id="container" style="position: absolute; top: 2px; left: 2px; bottom: 2px; right: 2px"></div>
      </div>
    </NGridItem>
  </NGrid>
</template>

<style lang="scss" scoped>
:deep(.n-tree) {
  .n-tree-node-content {
    --uno: px-8px py-4px;
  }
  .n-tree-node-content:hover .n-tree-node-content__suffix {
    display: inline-flex;
  }
}
table {
  border-top: 1px solid #e5e7eb;
  border-left: 1px solid #e5e7eb;

  td {
    border-right: 1px solid #e5e7eb;
    border-bottom: 1px solid #e5e7eb;
  }
}
</style>
